package com.polaris.live.ui.live.fragment.base

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import androidx.annotation.CallSuper
import androidx.core.view.GestureDetectorCompat
import androidx.viewbinding.ViewBinding
import com.polaris.live.common.ext.dp
import com.polaris.live.common.mvvm.base2.BaseVbFragment
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.widget.AnimUtils
import kotlin.math.abs

/**
 * 实现了隐藏显示手势
 *
 * @author Created by lucas on 2023/11/7 18:08
 */
abstract class GestureFragment<VM : BaseViewModel, VB : ViewBinding> : BaseVbFragment<VM, VB>(),
    OnGestureListener {

    private lateinit var mGestureDetector: GestureDetectorCompat

    private var mIsShowed = true

    @CallSuper
    override fun initView(savedInstanceState: Bundle?) {
        mGestureDetector = GestureDetectorCompat(requireContext(),
            object : SimpleOnGestureListenerKt() {
                override fun onFling(
                    e1: MotionEvent?,
                    e2: MotionEvent,
                    velocityX: Float,
                    velocityY: Float,
                ): Boolean {
                    if (e1 == null || !isGesture()) {
                        return false
                    }

                    if (abs(velocityX) > abs(velocityY) && abs(velocityX) > snapVelocity && abs(e1.x - e2.x) > snapMinDistance) {
                        if (e1.x - e2.x > 0) {
                            showView()
                        } else {
                            hideView()
                        }
                    }
                    return false
                }
            })
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        return if (!::mGestureDetector.isInitialized) {
            false
        } else {
            mGestureDetector.onTouchEvent(ev)
        }
    }

    private fun showView() {
        if (mIsShowed) {
            onShowRightView()
        } else {
            onShowView()
            mIsShowed = true
        }
    }

    private fun hideView() {
        if (!mIsShowed) {
            return
        }

        onHideView()
        mIsShowed = false
    }

    /**
     * 显示view
     */
    abstract fun onShowView()

    /**
     * 隐藏view
     */
    abstract fun onHideView()

    /**
     * 显示右边view
     */
    open fun onShowRightView() {

    }

    /**
     * 是否启动手势
     */
    open fun isGesture(): Boolean {
        return false
    }

    fun playAnim(list: List<Animator>) {
        AnimUtils.run(mBinding.root, AnimatorSet().apply {
            duration = 350
            playTogether(list)
        })
    }

    fun inLeft(view: View, start: Int): Animator {
        val animator = AnimatorSet().apply {
            playTogether(
                ObjectAnimator.ofFloat(view, "translationX", start.toFloat(), 0f),
                ObjectAnimator.ofFloat(view, "alpha", 0f, 1f),
            )
        }
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationStart(animation: Animator) {
                view.visibility = ViewUtils.getViewVisible(view) ?: View.VISIBLE
            }
        })
        return animator
    }

    fun inAlpha(view: View): Animator {
        val animator = AnimatorSet().apply {
            playTogether(
                ObjectAnimator.ofFloat(view, "alpha", 0f, 1f),
            )
        }
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationStart(animation: Animator) {
                view.visibility = ViewUtils.getViewVisible(view) ?: View.VISIBLE
            }
        })
        return animator
    }

    fun outAlpha(view: View): Animator {
        val animator = AnimatorSet().apply {
            playTogether(
                ObjectAnimator.ofFloat(view, "alpha", 1f, 0f),
            )
        }
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationStart(animation: Animator) {
                view.visibility = ViewUtils.getViewVisible(view) ?: View.GONE
            }
        })
        return animator
    }

    fun outRight(view: View, end: Int, visibility: Int = View.GONE): Animator {
        val animator = AnimatorSet().apply {
            playTogether(
                ObjectAnimator.ofFloat(view, "translationX", 0f, end.toFloat()),
                ObjectAnimator.ofFloat(view, "alpha", 1f, 0f),
            )
        }
        animator.addListener(object : AnimatorListenerAdapter() {
            override fun onAnimationEnd(animation: Animator) {
                view.visibility = ViewUtils.getViewVisible(view) ?: visibility
            }
        })
        return animator
    }

    companion object {

        private val snapVelocity = 800.dp //最小手势速度
        private val snapMinDistance = 25.dp //最小被判定为移动的距离
    }
}

fun interface OnGestureListener {

    fun dispatchTouchEvent(ev: MotionEvent): Boolean

}